const fs = require('fs');
const path = require('path');

// 日志级别
const LogLevel = {
  ERROR: 'ERROR',
  WARN: 'WARN',
  INFO: 'INFO',
  DEBUG: 'DEBUG'
};

// 日志级别优先级
const LogPriority = {
  ERROR: 0,
  WARN: 1,
  INFO: 2,
  DEBUG: 3
};

class Logger {
  constructor(options = {}) {
    this.level = options.level || process.env.LOG_LEVEL || 'INFO';
    this.logDir = options.logDir || process.env.LOG_FILE_PATH || './logs';
    this.enableConsole = options.enableConsole !== false;
    this.enableFile = options.enableFile !== false;
    
    // 确保日志目录存在
    if (this.enableFile && !fs.existsSync(this.logDir)) {
      fs.mkdirSync(this.logDir, { recursive: true });
    }
  }

  /**
   * 格式化日志消息
   */
  formatMessage(level, message, meta = {}) {
    const timestamp = new Date().toISOString();
    const metaStr = Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : '';
    return `[${timestamp}] [${level}] ${message}${metaStr}`;
  }

  /**
   * 写入日志到文件
   */
  writeToFile(level, message) {
    if (!this.enableFile) return;

    try {
      const date = new Date().toISOString().split('T')[0];
      const filename = path.join(this.logDir, `${date}.log`);
      fs.appendFileSync(filename, message + '\n', 'utf8');
    } catch (error) {
      console.error('写入日志文件失败:', error.message);
    }
  }

  /**
   * 输出日志到控制台
   */
  writeToConsole(level, message) {
    if (!this.enableConsole) return;

    const colors = {
      ERROR: '\x1b[31m', // 红色
      WARN: '\x1b[33m',  // 黄色
      INFO: '\x1b[36m',  // 青色
      DEBUG: '\x1b[90m'  // 灰色
    };
    const reset = '\x1b[0m';

    console.log(`${colors[level] || ''}${message}${reset}`);
  }

  /**
   * 记录日志
   */
  log(level, message, meta = {}) {
    // 检查日志级别
    if (LogPriority[level] > LogPriority[this.level.toUpperCase()]) {
      return;
    }

    const formattedMessage = this.formatMessage(level, message, meta);
    
    this.writeToConsole(level, formattedMessage);
    this.writeToFile(level, formattedMessage);
  }

  error(message, meta = {}) {
    this.log(LogLevel.ERROR, message, meta);
  }

  warn(message, meta = {}) {
    this.log(LogLevel.WARN, message, meta);
  }

  info(message, meta = {}) {
    this.log(LogLevel.INFO, message, meta);
  }

  debug(message, meta = {}) {
    this.log(LogLevel.DEBUG, message, meta);
  }

  /**
   * 记录HTTP请求
   */
  logRequest(req, res, responseTime) {
    const message = `${req.method} ${req.originalUrl} ${res.statusCode} ${responseTime}ms`;
    const meta = {
      method: req.method,
      url: req.originalUrl,
      statusCode: res.statusCode,
      responseTime,
      ip: req.ip || req.connection.remoteAddress,
      userAgent: req.get('user-agent')
    };

    if (res.statusCode >= 500) {
      this.error(message, meta);
    } else if (res.statusCode >= 400) {
      this.warn(message, meta);
    } else {
      this.info(message, meta);
    }
  }

  /**
   * 清理旧日志文件（保留最近N天）
   */
  cleanOldLogs(daysToKeep = 30) {
    if (!this.enableFile) return;

    try {
      const files = fs.readdirSync(this.logDir);
      const now = Date.now();
      const maxAge = daysToKeep * 24 * 60 * 60 * 1000;

      files.forEach(file => {
        const filePath = path.join(this.logDir, file);
        const stat = fs.statSync(filePath);
        
        if (now - stat.mtimeMs > maxAge) {
          fs.unlinkSync(filePath);
          this.info(`已删除旧日志文件: ${file}`);
        }
      });
    } catch (error) {
      this.error('清理日志文件失败', { error: error.message });
    }
  }
}

// 创建默认日志实例
const logger = new Logger();

// 定期清理日志（每天执行一次）
if (process.env.NODE_ENV !== 'test') {
  setInterval(() => {
    logger.cleanOldLogs(30);
  }, 24 * 60 * 60 * 1000); // 每24小时执行一次
}

module.exports = logger;

